package com.excetop.xservlet.req;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import com.excetop.xservlet.RUNTIME_CONST;
import com.excetop.xservlet.req.param.BooleanParam;
import com.excetop.xservlet.req.param.DoubleParam;
import com.excetop.xservlet.req.param.FileParam;
import com.excetop.xservlet.req.param.FloatParam;
import com.excetop.xservlet.req.param.IntParam;
import com.excetop.xservlet.req.param.JsonParam;
import com.excetop.xservlet.req.param.LongParam;
import com.excetop.xservlet.req.param.Param;
import com.excetop.xservlet.req.param.ShortParam;
import com.excetop.xservlet.req.param.TextParam;
import com.excetop.xservlet.req.param.TimestampParam;

/**
 * 请求参数表
 * @author xuZW
 *
 */
public class ParamMap extends HashMap<String, Param> implements RUNTIME_CONST {

	private static final long serialVersionUID = 1L;

	/**
	 * 添加参数, 如果指定的参数名字已存在, 则替换
	 * @param param
	 */
	public void add(Param param){
		if(null != param){
			this.put(param.getName(), param);
		}
	}
	
	/**
	 * 添加多媒体部分(文件)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws ServletException
	 */
	public void addFile(HttpServletRequest req, String paramName) throws IllegalStateException, IOException, ServletException{
		addFile(req, paramName, null);
	}
	
	/**
	 * 添加多媒体部分(文件)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws ServletException
	 */
	public void addFile(HttpServletRequest req, String paramName, String... patternArray) throws IllegalStateException, IOException, ServletException{
		List<Part> list = new ArrayList<Part>();
		for (Part part : req.getParts()) {
			if(paramName.equals(part.getName())){ list.add(part); }
		}
		this.put(paramName, new FileParam(paramName, list.toArray(new Part[0]), patternArray));
	}
	
	/**
	 * 添加一个新的文本参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addText(HttpServletRequest req, String paramName) {
		this.put(paramName, new TextParam(paramName, req.getParameterValues(paramName)));
	}
	
	/**
	 * 添加一个新的文本参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addText(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new TextParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的文本参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param encoding
	 * @throws UnsupportedEncodingException
	 */
	public void addText(HttpServletRequest req, String paramName, String encoding) throws UnsupportedEncodingException{
		addText(req, paramName, encoding, null);
	}
	
	/**
	 * 添加一个新的文本参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param encoding
	 * @param patternArray
	 * @throws UnsupportedEncodingException
	 */
	public void addText(HttpServletRequest req, String paramName, String encoding, String... patternArray) throws UnsupportedEncodingException{
		String[] paramValues = req.getParameterValues(paramName);
		if(null != paramValues && null != encoding){
			for (int i = 0; i < paramValues.length; i++) {
				paramValues[i] = null == paramValues[i] ? null : new String(paramValues[i].getBytes(encoding), DEFAULT_ENCODING);
			}
		}
		this.put(paramName, new TextParam(paramName, paramValues, patternArray));
	}
	
	/**
	 * 添加一个新的短整型(short)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addShort(HttpServletRequest req, String paramName) {
		addShort(req, paramName, null);
	}
	
	/**
	 * 添加一个新的短整型(short)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addShort(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new ShortParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的整型(int)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addInt(HttpServletRequest req, String paramName) {
		addInt(req, paramName, null);
	}
	
	/**
	 * 添加一个新的整型(int)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addInt(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new IntParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的长整型(long)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addLong(HttpServletRequest req, String paramName) {
		addLong(req, paramName, null);
	}
	
	/**
	 * 添加一个新的长整型(long)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addLong(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new LongParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的浮点型(float)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addFloat(HttpServletRequest req, String paramName) {
		addFloat(req, paramName, null);
	}
	
	/**
	 * 添加一个新的浮点型(float)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addFloat(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new FloatParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的双精度浮点型(double)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addDouble(HttpServletRequest req, String paramName) {
		addDouble(req, paramName, null);
	}
	
	/**
	 * 添加一个新的双精度浮点型(double)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addDouble(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new DoubleParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的布尔型(boolean)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addBoolean(HttpServletRequest req, String paramName) {
		addBoolean(req, paramName, null);
	}
	
	/**
	 * 添加一个新的布尔型(boolean)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addBoolean(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new BooleanParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的时间戳型(timestamp)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addTimestamp(HttpServletRequest req, String paramName) {
		addTimestamp(req, paramName, null);
	}
	
	/**
	 * 添加一个新的时间戳型(timestamp)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addTimestamp(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new TimestampParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的 JSON 型(json)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 */
	public void addJson(HttpServletRequest req, String paramName) {
		this.put(paramName, new JsonParam(paramName, req.getParameterValues(paramName)));
	}
	
	/**
	 * 添加一个新的 JSON 型(json)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param patternArray
	 */
	public void addJson(HttpServletRequest req, String paramName, String... patternArray) {
		this.put(paramName, new JsonParam(paramName, req.getParameterValues(paramName), patternArray));
	}
	
	/**
	 * 添加一个新的 JSON 型(json)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param encoding
	 * @throws UnsupportedEncodingException
	 */
	public void addJson(HttpServletRequest req, String paramName, String encoding) throws UnsupportedEncodingException {
		addJson(req, paramName, encoding, null);
	}
	
	/**
	 * 添加一个新的 JSON 型(json)参数, 如果指定的参数名字已存在, 则替换
	 * @param req
	 * @param paramName
	 * @param encoding
	 * @param patternArray
	 * @throws UnsupportedEncodingException
	 */
	public void addJson(HttpServletRequest req, String paramName, String encoding, String... patternArray) throws UnsupportedEncodingException {
		String[] paramValues = req.getParameterValues(paramName);
		if(null != paramValues && null != encoding){
			for (int i = 0; i < paramValues.length; i++) {
				paramValues[i] = null == paramValues[i] ? null : new String(paramValues[i].getBytes(encoding), DEFAULT_ENCODING);
			}
		}
		this.put(paramName, new JsonParam(paramName, paramValues, patternArray));
	}
	
	/**
	 * 返回多媒体部分(文件)参数值
	 * @param paramName
	 * @return
	 */
	public Part getFile(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((FileParam) param).getFileValue();
	}
	
	/**
	 * 返回多媒体部分(文件)数组参数值
	 * @param paramName
	 * @return
	 */
	public Part[] getFileArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((FileParam) param).getFileValueArray();
	}
	
	/**
	 * 返回文本(字符串)参数值
	 * @param paramName
	 * @return
	 */
	public String getText(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValue();
	}
	
	/**
	 * 返回文本(字符串)数组参数值
	 * @param paramName
	 * @return
	 */
	public String[] getTextArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValueArray();
	}
	
	/**
	 * 返回去除左右空格后的文本(字符串)参数值
	 * @param paramName
	 * @return
	 */
	public String getTextTrimmed(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValueTrimmed();
	}
	
	/**
	 * 返回去除左右空格后的文本(字符串)数组参数值
	 * @param paramName
	 * @return
	 */
	public String[] getTextArrayTrimmed(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValueArrayTrimmed();
	}
	
	/**
	 * 返回去除全部空白字符后的文本(字符串)参数值
	 * @param paramName
	 * @return
	 */
	public String getTextWithoutSpaceCharacter(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValueWithoutSpaceCharacter();
	}
	
	/**
	 * 返回去除全部空白字符后的文本(字符串)数组参数值
	 * @param paramName
	 * @return
	 */
	public String[] getTextArrayWithoutSpaceCharacter(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TextParam) param).getTextValueArrayWithoutSpaceCharacter();
	}
	
	/**
	 * 返回短整型(short)参数值
	 * @param paramName
	 * @return
	 */
	public short getShort(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((ShortParam) param).getShortValue();
	}
	
	/**
	 * 返回短整型(short)数组参数值
	 * @param paramName
	 * @return
	 */
	public short[] getShortArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((ShortParam) param).getShortValueArray();
	}
	
	/**
	 * 返回整型(int)参数值
	 * @param paramName
	 * @return
	 */
	public int getInt(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((IntParam) param).getIntValue();
	}
	
	/**
	 * 返回整型(int)数组参数值
	 * @param paramName
	 * @return
	 */
	public int[] getIntArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((IntParam) param).getIntValueArray();
	}
	
	/**
	 * 返回长整型(long)参数值
	 * @param paramName
	 * @return
	 */
	public long getLong(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((LongParam) param).getLongValue();
	}
	
	/**
	 * 返回长整型(long)数组参数值
	 * @param paramName
	 * @return
	 */
	public long[] getLongArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((LongParam) param).getLongValueArray();
	}
	
	/**
	 * 返回浮点型(float)参数值
	 * @param paramName
	 * @return
	 */
	public float getFloat(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((FloatParam) param).getFloatValue();
	}
	
	/**
	 * 返回浮点型(float)数组参数值
	 * @param paramName
	 * @return
	 */
	public float[] getFloatArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((FloatParam) param).getFloatValueArray();
	}
	
	/**
	 * 返回双精度浮点型(double)参数值
	 * @param paramName
	 * @return
	 */
	public double getDouble(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((DoubleParam) param).getDoubleValue();
	}
	
	/**
	 * 返回双精度浮点型(double)数组参数值
	 * @param paramName
	 * @return
	 */
	public double[] getDoubleArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((DoubleParam) param).getDoubleValueArray();
	}
	
	/**
	 * 返回布尔型(boolean)参数值
	 * @param paramName
	 * @return
	 */
	public boolean getBoolean(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((BooleanParam) param).getBooleanValue();
	}
	
	/**
	 * 返回布尔型(boolean)数组参数值
	 * @param paramName
	 * @return
	 */
	public boolean[] getBooleanArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((BooleanParam) param).getBooleanValueArray();
	}
	
	/**
	 * 返回时间戳型(timestamp)参数值
	 * @param paramName
	 * @return
	 */
	public Timestamp getTimestamp(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TimestampParam) param).getTimestampValue();
	}
	
	/**
	 * 返回时间戳型(timestamp)数组参数值
	 * @param paramName
	 * @return
	 */
	public Timestamp[] getTimestampArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((TimestampParam) param).getTimestampValueArray();
	}
	
	/**
	 * 返回 JSON 型(json)参数值
	 * @param paramName
	 * @return
	 */
	public Object getJson(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((JsonParam) param).getJsonValue();
	}
	
	/**
	 * 返回 JSON 型(json)数组参数值
	 * @param paramName
	 * @return
	 */
	public Object[] getJsonArray(String paramName){
		Param param = get(paramName);
		return null == param ? null : ((JsonParam) param).getJsonValueArray();
	}
	
	/**
	 * 验证参数表
	 * @return
	 */
	public boolean verifying(){
		boolean result = true;
		// TODO Auto-generated method stub
		return result;
	}
	
}
